<?php
/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2020-11-26 18:10:22
 * @LastEditors: ding-cx
 * @LastEditTime: 2020-12-01 18:13:58
 * @Description: file content
 */
 

class TokenVerify
{
    private $ci = null;
    public function __construct()
    {
        $this->ci =& get_instance();
          
        //JSON response
        // header('Content-type: application/json');
        // var_dump($this->ci);
    }

    // 校验用户的身份权限。
    public function verify()
    {
        // $this->ci->output->set_status_header(401);
        $state_code = $this->ci->config->item("status_code");
        
       
        // route白名单不检查token
        if ($this->checkRouteWhite()) {
            return;
        }
        
        // return;
        $authToken = $this->ci->input->get_request_header("X-Authorization", true);
        $this->ci->load->library('Jwt');
        $jwt=new Jwt();
        
        /*
        载荷 示例：
          $payload=array(
                    'iss'=>'dingadmin',
                    'iat'=>time(),
                    'exp'=>time()+config_item('login_exp'),
                    'nbf'=>time(),
                    'sub'=>$userData['user_id'],
                    'name' => $userData['user_name'],
                    'jti'=>md5(uniqid('JWT').time())
                );
                */
        $userInfoPayload = $jwt->verifyToken($authToken);
        if ($userInfoPayload) {
            // 如果安装了redis
            if(config_item('is_install_redis')){
                $this->ci->load->driver('cache');
                $redisToken = $this->ci->cache->redis->get($userInfoPayload['name']);//以user_name为key的token
                // 可能是其他地方登录，也可能是token的redis失效。这样就能解决token定义了过期时间就无法修改的问题。
                if (config_item('login_only_one_address') && $redisToken !== $authToken) {
                    $this->ci->output->send("token失效，请重新登录。", 50014);
                    exit;
                }
            }
            // 把载荷保存的用户信息保存起来，在后续的控制器、model中使用。直接获取config userInfo就可。
            $this->ci->config->set_item("userInfo", $userInfoPayload);
            return;
        } else {
            $this->ci->output->send("token失效，请重新登录。", 50014);
            exit;
        }
    }

    // 检查路由白名单，如果在名单内，则不进行token鉴权
    private function checkRouteWhite()
    {
        $ci = $this->ci;
        $ci->load->config('myconfig/route_white');
        $whiteList = $ci->config->item("route_white");

        $curRoute = $ci->uri->uri_string();
        $curRoute = "/". strtolower($curRoute);
        // $curRoute = str_replace('/','\/',$curRoute);
        // echo $curRoute;
        // echo json_encode($whiteList);
        $isWhite = 0;
        foreach ($whiteList as $item) {
            $itemLen = strlen($item);
            // echo substr($curRoute,0,$itemLen);
            // echo '--';
            // echo $item;
            // echo '--';
            if (substr($curRoute, 0, $itemLen) === strtolower($item)) {
                $isWhite = 1;
                break;
            }
        }
        // echo $isWhite;
        return $isWhite;
    }
}
